/**
 @author 迷途小羔羊
 2015.3.5
 */
namespace GYLite
{
												
				
	/**行列宽高固定的Grid组件，行列数量随组件宽高自适应，若单纯纵向建议使用GYGridV，单纯横向建议使用GYGridH*/
	export class GYGrid extends GYGridBase
	{
		protected _lastLineH:number;
		protected _lastEndLineH:number;
		protected _hScrollerPolicy:number;//水平滚动条 0自动 1显示 2不显示
		protected _horizonalMax:number;		
		/**行列宽高固定的Grid组件，行列数量随组件宽高自适应，若单列建议使用GYGridV，单行建议使用GYGridH
		 * @param cols 无效 
		 * @param rows 无效 
		 * @param getGridFunc():IItemRender 返回自定义格子对象的方法 
		 * @param setGridFunc(IItemRender, any) 设置格子数据的方法*/
		public constructor(cols:number,rows:number,getGridFunc:Function=null, getThisObject:any=null, setGridFunc:Function=null, setThisObject:any=null)
		{
			super(0,0,getGridFunc,getThisObject,setGridFunc,setThisObject);			
		}
		
		protected initComponent():void
		{
			let s = this;
			super.initComponent();			
			s._lastLineH = 0;
			s._lastEndLineH = 0;
			s._hScrollerPolicy = 0;
			s._horizonalMax = 0;
				
			s.baseAdd(s.vScroller);						
			s.baseAdd(s.hScroller);
			var grid:IItemRender;
			grid=s.getGrid();				
			s._settingBoxH = s._boxH = grid.height;
			s._settingBoxW = s._boxW = grid.width;	
			s._itemRatio = s._boxW / s._boxH;		
		}
		public set selectedIndex(val:number)
		{
			let s = this;
			throw(new Error("此为二维表，请使用s.selectedPos代替"));
		}		
		/**选择row行col列指定项*/
		public selectedPos(row:number,col:number)
		{
			let s = this;
			s.selectedData = s._dataProvider[row][col];
		}
		/**跳转到row行col列*/
		public scrollToPos(row:number=NaN,col:number=NaN):void
		{
			let s = this;
			if(row == row)s.vScroller.position = row * s._settingBoxH;
			if(col == col)s.hScroller.position = col * s._settingBoxW;
		}
		/**跳转到row行col列(位置在末尾)*/
		public scrollToEndPos(row:number=NaN,col:number=NaN):void
		{
			let s = this;
			if(row == row)s.vScroller.position = row * s._settingBoxH - s._innerHeight + s._settingBoxH;
			if(col == col)s.hScroller.position = col * s._settingBoxW - s._innerWidth + s._settingBoxW;
		}
		protected selectLine(data:any,selectedData:any,ctrlKey:boolean,checkNext:boolean=false):void
		{
			let s = this;
			var stRow:number=0,endRow:number=0,stCol:number=0,endCol:number=0;
			var ind:number=0;
			var i:number=0,j:number=0,len:number=0,len2:number=0;
			var tempItem:IItemRender;
			var tempData:any;
			var end:number=0, flag:number=0, flag2:number=0, mY:number = s.mouseY,mX:number = s.mouseX;
			var rowArray:Array<any>;
			var tempVec:any[];
			if(checkNext)
			{
				tempItem = s._dataToItemDict.getValue(data);
				if(mY > s.height)
					flag = 1;
				else if(mY < 0)
					flag = -1;
				if(mX > s.width)
					flag2 = 1;
				else if(mX < 0)
					flag2 = -1;
				if(flag == 0 && flag2 == 0)
					return;
			}
			len = s._dataProvider.length;
			stRow = -1;
			while(--len > -1)
			{
				rowArray = s._dataProvider[len];
				stCol = rowArray.indexOf(s.selectedData);
				if(stCol > -1)
				{
					stRow = len;
					break;
				}
			}
			len = s._dataProvider.length;
			endRow = -1;
			while(--len > -1)
			{
				rowArray = s._dataProvider[len];
				endCol = rowArray.indexOf(data);
				if(endCol > -1)
				{
					endRow = len;
					break;
				}
			}
			
			//拖选
			if(flag != 0 || flag2 != 0)
			{
				if(flag == 1)
					endRow = endRow < s._dataProvider.length - 1? endRow + 1: s._dataProvider.length - 1;
				else if(flag == -1)
					endRow = endRow > 0? endRow - 1: endRow;
				if(flag2 == 1)
					endCol = endCol < s._dataProvider[endRow].length - 1? endCol + 1: s._dataProvider[endRow].length - 1;
				else if(flag2 == -1)
					endCol = endCol > 0? endCol - 1: endCol;
				data = s._dataProvider[endRow][endCol];
				s.scrollToEndPos(endRow, endCol);
			}
			s._nextData = data;
			
			if(endRow < stRow)
			{
				ind = endRow;
				endRow = stRow;
				stRow = ind;
			}
			if(endCol < stCol)
			{
				ind = endCol;
				endCol = stCol;
				stCol = ind;
			}
			
			len = endRow + 1;
			len2 = endCol + 1;
			end = s._selectList.length-1;
			for(i=stRow;i<len;++i)
			{
				for(j=stCol;j<len2;++j)
				{
					tempData = s._dataProvider[i][j];
					ind = end > -1? s._selectList.lastIndexOf(tempData,end) : -1;
					if(ind == -1)
					{
						if(s._selectList.length >= s._canSelectNum)
							continue;
						if(tempData)
						{
							tempItem = s._dataToItemDict.getValue(tempData);
							s._selectList.push(tempData);
							if(tempItem)
								tempItem.selected = true;
						}
					}
					else if(!ctrlKey)
					{
						tempData = s._selectList[end];
						s._selectList[end] = s._selectList[ind];
						s._selectList[ind]= tempData;
						--end;
					}
				}
			}
			if(!ctrlKey && end > -1)
			{
				tempVec = s._selectList.splice(0,end + 1);
				len = tempVec.length;
				while(--len>-1)
				{
					tempItem = s._dataToItemDict.getValue(tempVec[len]);
					if(tempItem)
					{
						tempItem.selected = false;
					}
				}
			}
			if(s.hasEventListener(GYViewEvent.SELECTED) && s._mouseSelect)
			{
				s.dispatchEvent(new GYViewEvent(GYViewEvent.SELECTED));
				s._mouseSelect = false;
			}
		}		
		/**@inheritDoc*/
		public set dataProvider(val:Array<any>)
		{
			let s = this;
			let baseHeight:number,baseWidth:number;
			baseHeight = s.baseHeight;
			baseWidth = s.baseWidth;
			if(!s._keepSelected)
			{
				s._selectedData = null;
				s._selectIndex = -1;
				if(s._canSelectNum > 1)
					s._selectList.length = 0;
			}
			s._dataProvider=(val?val:[]);
			var w:number=s._settingBoxW + s._paddingR;
			var h:number=s._settingBoxH + s._paddingB;
			
			s._max = Math.max(s._dataProvider.length * h - s._paddingB, baseHeight) + s.hScroller.height;
			s.vScroller.maximum = s._max-baseHeight + s._scrollPadTop + s._scrollPadBottom;
			s.vScroller.barPercent = baseHeight/s._max;
			s.vScrollerPolicy = s._vScrollerPolicy;
			if(s.vScroller.position > s.vScroller.maximum)
				s.vScroller.position = s.vScroller.maximum;
			
			s._horizonalMax = (s._dataProvider[0]?Math.max(s._dataProvider[0].length * w - s._paddingR, baseWidth):baseWidth) + s.vScroller.width;
			s.hScroller.maximum = s._horizonalMax-baseWidth + s._scrollPadLeft + s._scrollPadRight;
			s.hScroller.barPercent = baseWidth/s._horizonalMax;
			s.hScrollerPolicy = s._hScrollerPolicy;
			if(s.hScroller.position > s.hScroller.maximum)
				s.hScroller.position = s.hScroller.maximum;
			
			s.vScrollChange(null, true);
			s.hScrollChange(null, true);
		}
		public get dataProvider():Array<any>
		{
			let s = this;
			return s._dataProvider;
		}
		protected vScrollChange(e:GYScrollerEvent=null, update:boolean = false, updatePos:boolean = true)
		{
			let s = this;
			if(s._dataProvider==null)
				return;
			var val:number;
			var w:number, h:number;
			var line:number, nowLine:number;
			var offset:number, offset2:number;
			var i:number,j:number;
			var grid:IItemRender;
			var gridRows:Array<any>;
			var endLine:number;
			w =s._settingBoxW + s._paddingR;
			h =s._settingBoxH + s._paddingB;
			val = s.vScroller.position;
			offset = val % h;
			offset2 = s.hScroller.position % w;
			nowLine = (val / h >> 0);
			line=s._lastLine-nowLine;
			endLine = s._rows - 1;
			if(line < 0)
			{
				if(-line<s._rows)
				{
					for(i=0;i<-line;++i)
					{
						gridRows = s._grids[0];
						s._grids.shift();
						s._grids.splice(endLine, 0, gridRows);						
					}
				}
			}
			else if(line > 0)
			{
				if(line<s._rows)
				{
					for(i=0;i<line;++i)
					{
						gridRows = s._grids[endLine];
						s._grids.splice(endLine,1);
						s._grids.unshift(gridRows);
					}
				}
			}
			var tempLine:number= s._rows + line - 1;
			var iLine:number,jLine:number;
			var obj:any;
			var isSet:boolean;
			for(i=0;i<s._rows;++i)
			{
				iLine = nowLine+i;
				isSet=(line > 0 && i < line || line < 0 && i > tempLine || update);
				for(j=0;j<s._cols;++j)
				{
					jLine = s._lastLineH + j;
					if(iLine >= s._dataProvider.length)
						obj = null;
					else
						obj = s._dataProvider[iLine][jLine];
					grid = s._grids[i][j];
					if(isSet)
					{
						grid.row = iLine;
						grid.col = jLine;
						s.setGrid(grid,obj);						
					}
					if(updatePos)
					{
						grid.x = w * j - offset2;
						grid.y = h * i - offset;						
						s.checkOutSize(grid,false);
					}					
				}
			}
			s._lastLine = nowLine;
		}
		protected hScrollChange(e:GYScrollerEvent=null, update:boolean = false, updatePos:boolean = true)
		{
			let s = this;
			if(s._dataProvider==null)
				return;
			var val:number;
			var w:number, h:number;
			var line:number,nowLine:number;
			var offsetX:number, offsetY:number;
			var i:number,j:number;
			var grid:IItemRender;
			var gridRows:Array<any>;
			var endLine:number;
			w =s._settingBoxW + s._paddingR;
			h =s._settingBoxH + s._paddingB;
			val = s.hScroller.position;
			offsetY = s.vScroller.position % h;
			offsetX = val % w;
			nowLine = (val / w >> 0);
			endLine = s._cols - 1;
			line=s._lastLineH-nowLine;
			if(line < 0)
			{
				if(-line<s._cols)
				{
					for(i=0;i<s._rows;++i)
					{
						gridRows = s._grids[i];
						for(j=0;j<-line;++j)
						{
							grid = gridRows[0];
							gridRows.shift();
							gridRows.splice(endLine, 0,grid);							
						}
					}
				}
			}
			else if(line > 0)
			{
				if(line<s._cols)
				{
					for(i=0;i<s._rows;++i)
					{
						gridRows = s._grids[i];
						for(j=0;j<line;++j)
						{
							grid = gridRows[endLine];
							gridRows.splice(endLine,1);
							gridRows.unshift(grid);
						}
					}
				}
			}
			var tempLine:number= s._cols + line - 1;
			var iLine:number,jLine:number;
			var obj:any;
			for(i=0;i<s._rows;++i)
			{
				iLine = s._lastLine + i;
				for(j=0;j<s._cols;++j)
				{
					grid = s._grids[i][j];
					jLine = nowLine + j;
					if(iLine >= s._dataProvider.length)
						obj = null;
					else
						obj = s._dataProvider[iLine][jLine];
					if(line > 0 && j < line || line < 0 && j > tempLine || update)
					{
						grid.row = iLine;
						grid.col = jLine;
						s.setGrid(grid,obj);
					}
					if(updatePos)
					{
						grid.x = w * j - offsetX;
						grid.y = h * i - offsetY;						
						s.checkOutSize(grid,false);
					}					
				}
			}
			
			s._lastLineH = nowLine;
		}
		/**@inheritDoc*/
		public updateItems():void
		{
			let s = this;
			s.vScrollChange(null,true, false);			
		}
		/**@inheritDoc*/
		public updateGrid()
		{
			let s = this;
			let gridRows:Array<any>;
			let grid:IItemRender;
			let w:number=0, h:number=0;
			let offsetY:number=0, offsetX:number=0;
			let len:number=0,len2:number=0, i:number=0,j:number=0;
			let iLine:number=0,jLine:number=0;
			let nowCols:number=0,nowRows:number=0;
			let st:number=0;
			let baseHeight:number,baseWidth:number;
			if(s._dataProvider == null)return;

			baseHeight = s.baseHeight;
			baseWidth = s.baseWidth;
			let obj:any;			
			
			offsetY = (s.vScroller.position % h >> 0);
			offsetX = (s.hScroller.position % w >> 0);
			w = s._settingBoxW + s._paddingR;
			h = s._settingBoxH + s._paddingB;
			nowCols = w > 0?Math.ceil(baseWidth / w)+1:1;
			nowRows = h > 0?Math.ceil(baseHeight / h)+1:1;
			
			s._max = Math.max(s._dataProvider.length * h - s._paddingB, baseHeight) + s.hScroller.height;
			s.vScroller.maximum = s._max-baseHeight + s._scrollPadTop + s._scrollPadBottom;
			s.vScroller.barPercent = baseHeight/s._max;
			s.vScrollerPolicy = s._vScrollerPolicy;

			s._horizonalMax = (s._dataProvider[0]?Math.max(s._dataProvider[0].length * w - s._paddingR, baseWidth):baseWidth) + s.vScroller.width;
			s.hScroller.maximum = s._horizonalMax-baseWidth + s._scrollPadLeft + s._scrollPadRight;
			s.hScroller.barPercent = baseWidth/s._horizonalMax;
			s.hScrollerPolicy = s._hScrollerPolicy;
			
			i = s._grids.length;
			if(s._grids[0]) st = s._grids[0].length;
			for(;i<nowRows;++i)
			{
				gridRows = s._grids[i] = [];
				iLine = s._lastLine+i;
				for(j=0;j<st;++j)
				{
					jLine = s._lastLineH+j;
					grid = gridRows[j] = s.getGrid();					
					if(s._dataProvider == null || iLine >= s._dataProvider.length)
						obj = null;
					else
						obj = s._dataProvider[iLine][jLine];
					grid.row = iLine;
					grid.col = jLine;
					s.setGrid(grid, obj);					
				}
			}
			len = s._grids.length;
			for(i=0;i<len;++i)
			{
				gridRows = s._grids[i];
				iLine = s._lastLine+i;
				for(j=st;j<nowCols;++j)
				{
					jLine = s._lastLineH+j;
					grid = gridRows[j] = s.getGrid();					
					if(s._dataProvider == null || iLine >= s._dataProvider.length)
						obj = null;
					else
						obj = s._dataProvider[iLine][jLine];
					grid.row = iLine;
					grid.col = jLine;
					s.setGrid(grid, obj);					
				}
			}
			
			if(nowRows > s._rows)
			{
				for(i=s._rows;i<nowRows;++i)
				{
					gridRows = s._grids[i];
					for(j=0;j<s._cols;++j)
					{
						grid = gridRows[j];
						grid.x = w * j - offsetX;
						grid.y = h * i - offsetY;
						s.addElement(grid);						
					}
				}
			}
			else
			{
				for(i=nowRows;i<s._rows;++i)
				{
					gridRows = s._grids[i];
					for(j=0;j<s._cols;++j)
						s.removeElement(gridRows[j]);						
				}
			}
			
			if(nowCols > s._cols)
			{
				for(i=0;i<nowRows;++i)
				{
					gridRows = s._grids[i];
					for(j=s._cols;j<nowCols;++j)
					{
						grid = gridRows[j];
						grid.x = w * j - offsetX;
						grid.y = h * i - offsetY;
						s.addElement(grid);
					}
				}
			}
			else
			{
				for(i=0;i<nowRows;++i)
				{
					gridRows = s._grids[i];
					for(j=nowCols;j<s._cols;++j)
						s.removeElement(gridRows[j]);
				}
			}
			s._cols = nowCols;
			s._rows = nowRows;
			let resetFlag:boolean;
			resetFlag =  s._itemCols != s._itemCols;
			if(resetFlag)			
			{
				s._itemCols = s._cols - 1;
				s._itemCols = Math.max(1,s._itemCols*s._boxW>s._innerWidth?Math.floor(s._innerWidth / w):s._itemCols);				
			}
			//行数不自动设定，让用户自己设置，不设置则认为保持item高度
			// if(s._itemRows != s._itemRows)			
			// {
			// 	s._itemRows = s._rows - 1;
			// 	s._itemRows = Math.max(1,s._itemRows*s._boxH>s._innerHeight?Math.floor(s._innerHeight / h):s._itemRows);
			// }	
				
			if(resetFlag && s._autoItemSize > 0)				
			{
				s.autoItemSize = s._autoItemSize;
				s.updateGrid();
				return;
			}
			for(i=0;i<s._rows;++i)
			{
				for(j=0;j<s._cols;++j)
				{
					grid=s._grids[i][j];
					grid.width = s._settingBoxW;
					grid.height = s._settingBoxH;
				}
			}
			
			s.vScrollChange();
			s.hScrollChange();
			if(s.hasEventListener(GYViewEvent.GRID_UPDATE))
				s.dispatchEvent(new GYViewEvent(GYViewEvent.GRID_UPDATE));
		}
		public set_width(val:number):boolean
		{
			let s = this;
			let flag:boolean;
			flag = super.set_width(val);
			s.hScroller.width = val;			
			s._innerWidth = val - (s.vScroller.parent?s.vScroller.width:0);
			s.autoItemSize = s._autoItemSize;
			s.invalidGrids();
			return flag;
		}		
		public set_height(val:number):boolean
		{
			let s = this;
			let flag:boolean;
			flag = super.set_height(val);
			s.vScroller.height = val;			
			s._innerHeight = val - (s.hScroller.parent?s.hScroller.height:0);
			s.autoItemSize = s._autoItemSize;
			s.invalidGrids();
			return flag;
		}
		public set autoItemSize(val:number)
		{
			let s = this;			
			s._autoItemSize = val;
			if(s._autoItemSize > 0)
			{
				if(s._itemCols != s._itemCols)
					return;				
				s.setBoxWidth(s._innerWidth / s._itemCols >> 0);
				if(s._autoItemSize == 2 && s._itemRatio == s._itemRatio)
					s.setBoxHeight(s._settingBoxW / s._itemRatio);
				else if(s._autoItemSize == 1 && s._itemRows == s._itemRows)									
					s.setBoxHeight(Math.floor(s._innerHeight/s._itemRows));
			}	
			else
			{
				s.setBoxWidth(s._boxW);
				s.setBoxHeight(s._boxH);
			}			
		}
		/**列表项非滚动方向自动适应组件尺寸,0不适应 1item朝非滚动方向拉伸适应 2item等比适应*/
		public get autoItemSize():number
		{
			return this._autoItemSize;
		}
		
		public set canSelectNum(val:number)
		{
			let s = this;
			var rowArray:Array<any>;
			if(val > 0)
			{
				if(s._dataToItemDict==null)
				{
					s._selectList = new Array<any>();
					s._dataToItemDict = new Dictionary();
					var len:number = s._grids.length;
					var len2:number;
					while(--len>-1)
					{
						rowArray = s._grids[len];
						len2 = rowArray.length;
						while(--len2>-1)
						{
							var obj:any = rowArray[len2].getData();
							if(obj)
								s._dataToItemDict.setValue(obj, rowArray[len2]);
						}
					}
				}
			}
			else
			{
				s.selectedItem = null;
				if(s._selectList)
					s._selectList.length = 0;
				s.invalidData();
			}
			
			s._canSelectNum = val;
		}
		public get canSelectNum():number
		{
			let s = this;
			return s._canSelectNum;
		}
		public set dragSelect(value:boolean)
		{
			let s = this;
			s._dragSelect = value;
			var len:number,len2:number;
			var item:IItemRender;
			var rowArray:Array<any>;
			len = s._grids.length;
			while(--len>-1)
			{
				rowArray = s._grids[len];
				len2 = rowArray.length;
				while(--len2>-1)
				{
					item = rowArray[len2];
					if(s._dragSelect)
					{
						item.removeEventListener(egret.TouchEvent.TOUCH_END, s.selectCell,s);
						item.addEventListener(egret.TouchEvent.TOUCH_BEGIN, s.selectCell,s);
						item.addEventListener(MouseEvent.ROLL_OVER, s.selectCell,s);
					}
					else
					{
						item.removeEventListener(egret.TouchEvent.TOUCH_BEGIN, s.selectCell,s);
						item.removeEventListener(MouseEvent.ROLL_OVER, s.selectCell,s);
						item.addEventListener(egret.TouchEvent.TOUCH_END, s.selectCell,s);
					}
				}
			}
		}
		public get dragSelect():boolean
		{
			let s = this;
			return s._dragSelect;
		}
		/**获取列表视图范围内可见的最大最小行列
		 * @return [minRow, maxRow, minCol, maxCol]
		 * */
		public getRowColInView():number[]
		{
			let s= this;
			let arr:number[];
			let len:number,len2:number;
			let grid:IItemRender;
			arr = [Number.MAX_VALUE,0,Number.MAX_VALUE,0];
			len = s._grids.length;
			while(--len>-1)
			{
				len2 = s._grids[len].length;
				while(--len2>-1)
				{
					grid = s._grids[len][len2];
					if(grid.x < 0 || grid.x + grid.width > s.width)
						continue;
					if(grid.y < 0 || grid.y + grid.height > s.height)
						continue;
					if(arr[0] > grid.row)
						arr[0] = grid.row;
					if(arr[1] < grid.row)
						arr[1] = grid.row;
					if(arr[2] > grid.col)
						arr[2] = grid.col;
					if(arr[3] < grid.col)
						arr[3] = grid.col;
				}				
			}
			return arr;
		}		
		protected wheelRoll(e)
		{
			let s = this;
			if(!s._wheelScroll)return;
			if(s._isDragging && s.dragForbiddenWheel)return;
			var val:number = s._wheelStep;
			val = s._wheelStep == 0?s._settingBoxH:s._wheelStep;
			s.vScroller.setPosition(s.vScroller.position+(e.deltaY > 0?val:-val),true);
		}
		/**水平滚动条 0自动 1显示 2不显示*/
		public get hScrollerPolicy():number
		{
			let s = this;
			return s._hScrollerPolicy;
		}
		public set hScrollerPolicy(val:number)
		{
			let s = this;
			s._hScrollerPolicy=val;
			var show:boolean;
			if(s._hScrollerPolicy == 0)
			{
				if(s.hScroller.barPercent < 1)
					show = true;
				else
					show = false;
			}
			else if(s._hScrollerPolicy == 1)
				show = true;
			else
				show = false;
			if(show)
			{
				if(s.hScroller.parent == null)
				{
					s.baseAdd(s.hScroller);
					s.set_height(s.$height);					
				}
			}
			else
			{
				if(s.hScroller.parent)
				{
					s.baseRemove(s.hScroller);
					s.set_height(s.$height);
				}
			}
		}
		/**垂直滚动条 0自动 1显示 2不显示*/
		public get vScrollerPolicy():number
		{
			let s = this;
			return s._vScrollerPolicy;
		}
		public set vScrollerPolicy(val:number)
		{
			let s = this;
			s._vScrollerPolicy=val;
			var show:boolean;
			if(s._vScrollerPolicy == 0)
			{
				if(s.vScroller.barPercent < 1)
					show = true;
				else
					show = false;
			}
			else if(s._vScrollerPolicy == 1)
				show = true;
			else
				show = false;
			if(show)
			{
				if(s.vScroller.parent == null)
				{
					s.baseAdd(s.vScroller);
					s.set_width(s.$width);					
				}
			}
			else
			{
				if(s.vScroller.parent)
				{
					s.baseRemove(s.vScroller);
					s.set_width(s.$width);
				}
			}
		}
		protected downGroup(e:egret.TouchEvent)
		{
			let s = this;
			if(s.mouseX >= s.vScroller.x && s.mouseX <= s.vScroller.x + s.vScroller.width)
				return;
			if(s.mouseY >= s.hScroller.y && s.mouseY <= s.hScroller.y + s.hScroller.height)
				return;
			s._touchId = e.touchPointID;
			if(GYSprite.pushGlobalDrag(this))
				s.groupDrag();
			else
				s.addEventListener(GYEvent.GLOABL_DRAG, s.globalDragCall,s);
		}
		protected dragLoop(t:number):void
		{
			let s = this;			
			var mX:number,mY:number;			
			let xFlag:boolean,yFlag:boolean;			
			let nt:number;
			let frameParam:number;
			let temp:number;
			nt = Date.now();
			frameParam = 1000/egret.ticker.$frameRate|0;
			xFlag = s._moveXTime < 100;
			yFlag = s._moveYTime < 100;
			s._moveXTime = xFlag?s._moveXTime + Math.min(frameParam,nt - s._lastXDragTime):Math.min(frameParam,nt - s._lastXDragTime);
			s._moveYTime = yFlag?s._moveYTime + Math.min(frameParam,nt - s._lastYDragTime):Math.min(frameParam,nt - s._lastYDragTime);
			mX = s.mouseX - s._clipRect.x;
			mY = s.mouseY - s._clipRect.y;
			s._lastYDragTime = s._lastXDragTime = nt;
			temp = s.tempY - mY;
			if(s._dragLock || Math.abs(temp) > s.dragValue)
			{
				s._isDragging = true;
				s.dragLock = true;
				s.easeSpeedY = yFlag?s.easeSpeedY + temp:temp;
				s.vScroller.position += s.easeSpeedY;
				s.tempY = mY;
				if(s.vScroller.position == 0 && s.easeSpeedY < 0 || s.vScroller.position == s.vScroller.maximum && s.easeSpeedY > 0)
				{
					if(GYSprite.shiftGlobalDrag(1))
					{
						s.clearGlobalDrag();
						return;
					}
				}
			}
			else if(GYLite.GYSprite.hasGlobalHDrag())
			{
				let dragMoveX:boolean;
				var mX:number = s.mouseX - s._clipRect.x;
				dragMoveX = Math.abs(s.tempX - mX) > s.dragValue;
				s.tempX = mX;
                if(dragMoveX)
					++GYLite.GYSprite.globalHDrag;
                if(GYLite.GYSprite.globalHDrag > GYLite.GYSprite.globalHDragCount)
                {
                    if (GYLite.GYSprite.shiftGlobalDrag(1))
                        s.clearGlobalDrag();
                }
			}
			temp = s.tempX - mX;
			if(s._dragLock || Math.abs(temp) > s.dragValue)
			{
				s._isDragging = true;
				s.dragLock = true;
				s.easeSpeedX = xFlag?s.easeSpeedX + temp:temp;
				s.hScroller.position += s.easeSpeedX;
				s.tempX = mX;
				if(s.hScroller.position == 0 && s.easeSpeedX < 0 || s.hScroller.position == s.hScroller.maximum && s.easeSpeedX > 0)
				{
					if(GYSprite.shiftGlobalDrag(2))
					{
						s.clearGlobalDrag();
						return;
					}
				}
			}
			else if(GYLite.GYSprite.hasGlobalVDrag())
			{
				let dragMoveY:boolean;
				var mY:number = s.mouseY - s._clipRect.y;
				dragMoveY = Math.abs(s.tempY - mY) > s.dragValue;
				s.tempY = mY;
                if(dragMoveY)
					++GYLite.GYSprite.globalVDrag;
                if(GYLite.GYSprite.globalVDrag > GYLite.GYSprite.globalVDragCount)
                {
                    if (GYLite.GYSprite.shiftGlobalDrag(2))
                        s.clearGlobalDrag();
                }
			}
		}
		protected groupDrag():void
		{
			let s = this;
			if(s.vScroller.tween || s.hScroller.tween)s.dragLock = true;
			// CommonUtil.addStageLoop(s.dragLoop,s);
			GYSprite.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,s.touchMove,s);
			s._lastYDragTime = s._lastXDragTime = Date.now();
			s.vScroller.stopScroll();
			s.hScroller.stopScroll();
			s.tempY =  s.mouseY - s._clipRect.y;
			s.tempX =  s.mouseX - s._clipRect.x;
			s.easeSpeedX = s.easeSpeedY = 0;
			GYSprite.addStageDown(s,s.upGroup, s);
			s.addEventListener(egret.TouchEvent.TOUCH_END, s.upGroup, s);
		}
		protected groupDragStop():void
		{
			let s = this;
			if(s.tempY != s.tempY && s.tempX != s.tempX)return;
			let dis:number,minDis:number;
			let temp:number,tarPos:number,addDis:number;
			let frameParam:number;
			let dt:number,spd:number;			
			s._isDragging = false;
			frameParam = 1000/egret.ticker.$frameRate;
			s.removeEventListener(egret.TouchEvent.TOUCH_END, s.upGroup, s);
			// CommonUtil.delStageLoop(s.dragLoop,s);
			GYSprite.stage.removeEventListener(egret.TouchEvent.TOUCH_MOVE,s.touchMove,s);
			let nt:number = Date.now();
			dt = s._moveXTime;
			if(dt > 0 && nt - s._lastYDragTime < s._easeTriggerTime && (s.easeSpeedY > s.easeValue || s.easeSpeedY < -s.easeValue))
			{				
				spd = s.easeSpeedY / dt * frameParam;
				dis = (s.vScroller.limitMax == s.vScroller.limitMax && s.vScroller.limitMax < s.vScroller.maximum)?s.vScroller.limitMax:s.vScroller.maximum;
				minDis = (s.vScroller.limitMin == s.vScroller.limitMin && s.vScroller.limitMin > 0)?s.vScroller.limitMin:0;
				addDis = Math.abs(spd) * spd * s._easeSpeedValue;
				temp = s.vScroller.position + addDis;
				if(temp < minDis)
				{
					tarPos = minDis;
					addDis = tarPos - s.vScroller.position;
				}						
				else if(temp > dis)
				{
					tarPos = dis;
					addDis = tarPos - s.vScroller.position;
				}
				else
				{
					tarPos = temp;					
				}
				let t:number = (temp < minDis || temp > dis)?s._easeTime:Math.abs(addDis / spd * frameParam * 2);
				s.vScroller.scrollToPosition(tarPos, t);
			}
			dt = s._moveYTime;
			if(dt > 0 && nt - s._lastXDragTime < s._easeTriggerTime && (s.easeSpeedX > s.easeValue || s.easeSpeedX < -s.easeValue))
			{				
				spd = s.easeSpeedX / dt * frameParam;
				dis = (s.hScroller.limitMax == s.hScroller.limitMax && s.hScroller.limitMax < s.hScroller.maximum)?s.hScroller.limitMax:s.hScroller.maximum;
				minDis = (s.hScroller.limitMin == s.hScroller.limitMin && s.hScroller.limitMin > 0)?s.hScroller.limitMin:0;
				addDis = Math.abs(spd) * spd * s._easeSpeedValue;
				temp = s.hScroller.position + addDis;
				if(temp < minDis)
				{
					tarPos = minDis;
					addDis = tarPos - s.hScroller.position;
				}						
				else if(temp > dis)
				{
					tarPos = dis;
					addDis = tarPos - s.hScroller.position;
				}
				else
				{
					tarPos = temp;					
				}
				let t:number = (temp < minDis || temp > dis)?s._easeTime:Math.abs(addDis / spd * frameParam * 2);
				s.hScroller.scrollToPosition(tarPos, t);
			}
			s.dragLock = false;
		}
	}
}